// 数组类型
let names1: Array<string> = []; // 不推荐
let names2: string[] = []; // 推荐

// null undefined
let n1: null = null;
let n2: undefined = undefined;

// 对象类型
const info = {
  name: 'zhansan',
  age: 18
}

interface InfoType {
  name: string
  age: number
}

// 通过interface来定义索引类型
interface IndexLanguage {
  [index: number]: string
}
const obj: IndexLanguage = {
  0: 'html',
  1: 'css',
  2: 'js'
  // 'xxx': 'js' // 报错
}

// 元组类型 tuple
const arr: [string, number] = ['qwe', 123]; // 类型放括号里面，必须给值

// 联合类型
let aaa: string | number = 12;

// 类型别名
type IDType = string | number
let id: IDType = 123;

// 断言
// as
// 后面加 ! 是非空断言

// 可选链    ?.
// obj.info?.name  如果info不存在直接返回undefined，存在就继续执行

//  ?? 和 !! 这并不是typescript提供的 js里就有
let val: string | null = null;
let aa = val ?? '123'; // 如果val的值为null或undefined，那么aa就是后面的值，类似判断val存不存在的意思

let bool: boolean = !!val; // 就是转成布尔值

// 字面量类型
let msg: 123 = 123;
let msg2: 123 | 'qwe' = 123; // 字面量类型的意义要结合联合类型
// 如
type Align = 'left' | 'center' | 'right';
let pos: Align = 'center'; // 只能是上面几个中的一个 

// 函数类型
function foo(fn: () => void) {
  fn()
}

// type FnType = (num1: number, num2: number) => void; // void的时候返回任何类型都不报错
type FnType = (num1: number, num2: number) => number;
const add: FnType = (num1: number, num2: number): number => {
  return num1 + num2;
}

// 枚举类型  // 感觉就是一些标识性的常量
enum Direction {
  LEFT, // 不给值也是有值的，0  1  2  3
  RIGHT, // 1
  TOP, // 2
  BOTTOM // 3
}
// 也可以给值, 不给值就会按照 01234来
// enum Direction {
//   LEFT = 111,
//   RIGHT = 222,
//   TOP = 333,
//   BOTTOM = 444
// }
function turnDirection(direction: Direction) {
  console.log(direction);
  if (direction === Direction.LEFT) {
    console.log(direction);
  }
}
turnDirection(Direction.LEFT);

// 泛型
// 泛型最基本使用
function foo2<A, B, C>(arg1: A, arg2: B, arg3: C) {

}
foo2<string, number, boolean>('d', 3, true);

// 泛型类型约束举例
interface AAA {
  length: number
}

function getLength<T extends AAA>(arg: T) {
  return arg.length
}

getLength('qwe');

// .d.ts 文件  用来做类型的声明，仅仅用来做类型检测，告诉typescript我们有哪些类型

// ts 中的Pick
type Tabs = {
  name: string,
  comName: any
}

type Com = Pick<Tabs, 'comName'>
